<template>
  <div>
    <a-popover trigger="click" title="字段筛选" placement="bottomRight" @open-change="change">
      <a-tooltip title="字段筛选">
        <a-button type="link">
          <FilterOutlined />
        </a-button>
      </a-tooltip>
      <template #content>
        <div class="pop-content w-full">
          <ul class="w-full grid grid-cols-3 gap-4" ref="el">
            <li v-for="(item, key) in cols" :key="item.key" class="cursor-move">
              <div class="flex items-center gap-2">
                <a-badge :count="key + 1" color="#d6d6d6"></a-badge>
                <span>
                  {{ item.title }}
                </span>
              </div>
              <div class="ml-4">
                <a-checkbox v-model:checked="item.show" @change="onChange"></a-checkbox>
              </div>
            </li>
          </ul>
          <div class="divider text-right w-full">
            <a-tooltip title="更新本地数据">
              <a-button type="link" @click="reset">
                还原
                <template #icon>
                  <ReloadOutlined />
                </template>
              </a-button>
            </a-tooltip>
          </div>
        </div>
      </template>
    </a-popover>
  </div>
</template>

<script setup lang="ts">
import useColumnsStore from '@/store/columns/index';
import { type TableColumnType } from 'ant-design-vue';
import { moveArrayElement, useSortable } from '@vueuse/integrations/useSortable';

interface ColumnProps extends TableColumnType {
  show?: boolean;
}
const el = ref();
const firstLoad = ref(true);
const emit = defineEmits(['update:columns']);
const cols = ref<any[]>([]);

const store = useColumnsStore();

const props = defineProps<{
  columns: ColumnProps[];
  /* 模块名，必须，用于区分本地存储的列 */
  moduleName: string;
  raw: ColumnProps[];
}>();
const onChange = () => {
  store.$state.data = store.$state.data.map(e => {
    if (e.moduleName === props.moduleName) {
      e.columns = cols.value;
      return e;
    }
    return e;
  });
  emit('update:columns', cols.value);
};

const getRawColumns = () => {
  return props.raw.map(e => {
    if (typeof e.show === 'undefined') {
      e.show = true;
    } else if (typeof e.show === 'boolean' && !e.show) {
      e.show = true;
    }
    return e;
  });
};
const change = () => {
  if (firstLoad.value) {
    nextTick(() => {
      useSortable(el, cols, {
        animation: 200,

        onUpdate(e: any) {
          console.log(cols.value);
          moveArrayElement(cols.value, e.oldIndex, e.newIndex);
          emit('update:columns', cols.value);
        },
      });
    });
    firstLoad.value = false;
  }
};
/**
 * @description:
 * 还原所有列
 */
const reset = () => {
  cols.value = getRawColumns();

  store.$state.data = store.$state.data.map(e => {
    if (e.moduleName === props.moduleName) {
      e.columns = cols.value;
    }
    return e;
  });
  emit('update:columns', cols.value);
};
/**
 * @description:
 * 初始化
 * 判断本地是否存储列
 * 没有存储则创建，有则读取
 */
const init = () => {
  const target = store.$state.data.find(e => {
    if (e.moduleName === props.moduleName) {
      return e;
    }
    return null;
  });
  if (!target) {
    /* 初始化 */
    let columns = getRawColumns();
    store.$state.data.push({
      columns: columns as any,
      moduleName: props.moduleName,
    });
    cols.value = getRawColumns();
  } else {
    cols.value = target.columns;
  }
  emit('update:columns', cols.value);
};
watch(
  props,
  () => {
    init();
  },
  {
    immediate: true,
    deep: true,
  },
);
</script>

<style lang="scss" scoped>
.pop-content {
  li {
    white-space: nowrap;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    user-select: none;
    padding: 0.5rem;
    &:hover {
      background-color: var(--background-color);
    }
  }
}

.divider {
  border-top: 1px solid var(--border-color);
  padding-top: 8px;
  margin-top: 8px;
}
</style>
